import ArrayUtil from '@/ArrayUtil';
import AttributeUtil from '@/AttributeUtil';
import { d_increase_skill } from 'xlsx/increase_skill';
import RandomCommon from '../Common/RandomCommon';
import BaseUtil from '@/BaseUtil';
import HeroUtil from '@/HeroUtil';
import RandomUtil from '@/RandomUtil';
import PlayerUtil from '@/PlayerUtil';

export default class AbilityIncreaseSystem {
    vColor = '|cff9deb0e';
    colors: string[] = ['', '|cff38f309', '|cff09a7e6', '|cfff309ad', '|cfff39509', '|cfff30727'];
    DB: { [key: string]: t_increase_skill } = {};
    effctKes: string[];
    constructor() {
        this.init();
    }
    init() {
        let d = d_increase_skill;
        for (let item of d) {
            this.DB[item.key] = item;
        }
        this.effctKes = Object.keys(this.DB);

        se.onUnitPickupItem(this.pickupItem.bind(this));
        se.onUnitDropItem(this.lostItem.bind(this));
        se.onUnitPawnItem(this.lostItem.bind(this));
        se.onUnitSellItem(this.lostItem.bind(this));

        // se.onUnitSpellEffect(this.refreshItemIncrease.bind(this), 'A004');
        se.onUnitSpellEffect(this.increaseAbilityByClassId.bind(this));
    }
    canEffectAbilityIds: string[] = ['A004', 'A005', 'A006', 'A007', 'A008', 'A009', 'A00A', 'A00B', 'A00C', 'A00D', 'A00E', 'A00F'];
    increaseAbilityByClassId() {
        let id = id2string(GetSpellAbilityId());

        // 排除转移单位物品的技能
        if (id == 'He05') return;

        let it = GetSpellTargetItem();
        if (!this.canEffectAbilityIds.includes(id)) {
            // UnitAddItemById(GetTriggerUnit(), GetItemTypeId(it));
            return;
        }
        // 不能对消耗品使用
        if (GetItemType(it) == ITEM_TYPE_CHARGED) {
            // UnitAddItemById(GetTriggerUnit(), GetItemTypeId(it));
            PlayerUtil.message('该物品无法强化');
            return;
        }
        let itAttr = this.clearItemIncrease(it);
        if (id == 'A004') {
            this.refreshItemIncrease(it);
        }
        // 战士
        if (id == 'A005') {
            let attr = this.increaseByClass(['ZS'], RandomCommon.randomIntByWeight(1, 5, 1.5));
            AttributeUtil.add(itAttr, attr);
        }
        // 法师
        if (id == 'A006') {
            let attr = this.increaseByClass(['FS'], RandomCommon.randomIntByWeight(1, 5, 1.5));
            AttributeUtil.add(itAttr, attr);
        }
        // 盗贼
        if (id == 'A007') {
            let attr = this.increaseByClass(['DZ'], RandomCommon.randomIntByWeight(1, 5, 1.5));
            AttributeUtil.add(itAttr, attr);
        }
        // DK
        if (id == 'A008') {
            let attr = this.increaseByClass(['DK'], RandomCommon.randomIntByWeight(1, 5, 1.5));
            AttributeUtil.add(itAttr, attr);
        }
        // 德鲁伊
        if (id == 'A009') {
            let attr = this.increaseByClass(['DLY'], RandomCommon.randomIntByWeight(1, 5, 1.5));
            AttributeUtil.add(itAttr, attr);
        }
        // 骑士
        if (id == 'A00A') {
            let attr = this.increaseByClass(['QS'], RandomCommon.randomIntByWeight(1, 5, 1.5));
            AttributeUtil.add(itAttr, attr);
        }
        // 牧师
        if (id == 'A00B') {
            let attr = this.increaseByClass(['MS'], RandomCommon.randomIntByWeight(1, 5, 1.5));
            AttributeUtil.add(itAttr, attr);
        }
        // 游侠
        if (id == 'A00C') {
            let attr = this.increaseByClass(['YX'], RandomCommon.randomIntByWeight(1, 5, 1.5));
            AttributeUtil.add(itAttr, attr);
        }
        // 萨满
        if (id == 'A00D') {
            let attr = this.increaseByClass(['SM'], RandomCommon.randomIntByWeight(1, 5, 1.5));
            AttributeUtil.add(itAttr, attr);
        }
        // 武僧
        if (id == 'A00E') {
            let attr = this.increaseByClass(['WS'], RandomCommon.randomIntByWeight(1, 5, 1.5));
            AttributeUtil.add(itAttr, attr);
        }
        // 术士
        if (id == 'A00F') {
            let attr = this.increaseByClass(['SS'], RandomCommon.randomIntByWeight(1, 5, 1.5));
            AttributeUtil.add(itAttr, attr);
        }
    }
    clearItemIncrease(it: item) {
        let attr = AttributeUtil.getItemAttribute(it, true);
        if (attr != null) {
            for (let key in attr) {
                if (this.effctKes.includes(key)) {
                    delete attr[key];
                }
            }
        }
        return attr;
    }
    refreshItemIncrease(item: item) {
        let attr = this.clearItemIncrease(item);
        let nAttr = this.increasReward();
        AttributeUtil.add(attr, nAttr);
    }
    getKesByClassIds(cls: string[]) {
        let keys: string[] = [];
        for (let key in this.DB) {
            let v = this.DB[key];
            if (cls.includes(v.id)) {
                keys.push(v.key);
            }
        }
        return keys;
    }
    increaseByClass(cls: string[], count?: number) {
        let keys = this.getKesByClassIds(cls);
        count = count || 1;
        let attr: AppAttribute = {};
        for (let i = 0; i < count; i++) {
            let t = this.randomIncrese(keys);
            AttributeUtil.add(attr, t);
        }
        return attr;
    }
    increasReward(keys?: string[]) {
        let r = RandomUtil.randomPercent();
        // 60% 的机率附加强化效果
        let i = 1;
        if (r < 0.5) {
            i = 2;
        } else if (r < 0.25) {
            i = 3;
        } else if (r < 0.125) {
            i = 4;
        } else if (r < 0.0625) {
            i = 5;
        } else if (r < 0.03125) {
            i = 6;
        }
        let attr: AppAttribute = {};
        for (let j = 0; j < i; j++) {
            let t = this.randomIncrese(keys);
            AttributeUtil.add(attr, t);
        }
        return attr;
    }
    pickupItem() {
        let u = GetTriggerUnit();
        if (!HeroUtil.isHero(u)) return;
        let it = GetManipulatedItem();
        let attr = AttributeUtil.getItemAttribute(it);
        if (attr != null) {
            for (let key in attr) {
                if (key.includes('_lv_up')) {
                    BaseUtil.runLater(0.1, () => {
                        se.emit(GameEvents.技能强化, { u });
                    });
                    break;
                }
            }
        }
    }
    lostItem() {
        let u = GetTriggerUnit();
        if (!HeroUtil.isHero(u)) return;
        let it = GetManipulatedItem();
        let attr = AttributeUtil.getItemAttribute(it);
        if (attr != null) {
            for (let key in attr) {
                if (key.includes('_lv_up')) {
                    BaseUtil.runLater(0.1, () => {
                        se.emit(GameEvents.取消技能强化, { u });
                    });
                    break;
                }
            }
        }
    }
    getItemIncreaseTip(item: item, attr?: AppAttribute) {
        if (item != null) {
            attr = AttributeUtil.getItemAttribute(item, true);
        }
        if (attr == null) return '';
        let tips: string[] = [];
        for (let key in attr) {
            if (this.effctKes.includes(key)) {
                let d = this.DB[key];
                if (d.valueType == 'percent') {
                    let v = attr[key] as number;
                    if (v < 1) {
                        tips.push(`${d.desc} ${this.vColor}${R2I((attr[key] as number) * 100)}%`);
                    } else {
                        tips.push(`${d.desc} ${this.vColor}${R2I((attr[key] as number) * 100)}%`);
                    }
                } else if (d.valueType == 'bool') {
                    tips.push(`${d.desc}`);
                } else {
                    tips.push(`${d.desc} ${this.vColor}${attr[key]}`);
                }
            }
        }
        if (tips.length <= 0) return '';
        let len = tips.length > 5 ? 5 : tips.length;
        return `|n${this.colors[len]}[技能强化]|r|n` + tips.join('|n');
    }
    randomIncrese(keys?: string[]): AppAttribute {
        let attr: AppAttribute = {};
        let key = ArrayUtil.randomElement(keys || this.effctKes);
        let d = this.DB[key];
        let val: any = null;
        if (d.valueType == 'percent' || d.valueType == 'float') {
            val = RandomCommon.randomRealByWeight(d.min, d.max);
        } else if (d.valueType == 'int') {
            val = RandomCommon.randomIntByWeight(d.min, d.max);
        } else if (d.valueType == 'bool') {
            val = 1;
        }
        attr[key] = val;
        return attr;
    }
}
